#include "MySqlConn.h"

#include "log/Log.h"


namespace db 
{

MySqlConn::MySqlConn(const std::string& charset)
{
    m_mysql = mysql_init(nullptr);
    if (nullptr == m_mysql)
    {
        LOG_FMT_ERROR(g_sysLogger, "mysql init error, errorno: %d, errmsg: %s", errorno(), errmsg().c_str());
        return;
    }

    setCharSet(charset);
}
        
MySqlConn::~MySqlConn()
{
    freeResult();

    if (nullptr != m_mysql)
    {
        mysql_close(m_mysql);
    }
}
        
bool MySqlConn::connect(MySqlConf conf)
{
    return connect(conf.getDb()
                , conf.getUser()
                , conf.getPassword()
                , conf.getIp()
                , conf.getPort());
}

bool MySqlConn::connect(const std::string& db
                , const std::string& user, const std::string& password
                , const std::string& ip, uint16_t port)
{
    m_mysql = mysql_real_connect(m_mysql, ip.c_str(), user.c_str()
                                , password.c_str(), db.c_str(), port, nullptr, 0);
    if (nullptr == m_mysql)
    {
        LOG_FMT_ERROR(g_sysLogger, "mysql connect error, ip: %s, user: %s \
                    , password: %s, db: %s, port: %d, errorno: %d, errmsg: %s" \
                    , ip.c_str(), user.c_str(), password.c_str(), db.c_str(), port \
                    , errorno(), errmsg().c_str());
        return false;
    }
    return true;
}

bool MySqlConn::excute(const std::string& sql)
{
    freeResult();

    if (mysql_query(m_mysql, sql.c_str()))
    {
        LOG_FMT_ERROR(g_sysLogger, "mysql excute error, sql: %s, errorno: %d, errmsg: %s"
                    ,sql.c_str() , errorno(), errmsg().c_str());
        return false;
    }
    m_result = mysql_store_result(m_mysql);
    return true;
}

unsigned int MySqlConn::row()
{
    return mysql_num_rows(m_result);
}

unsigned int MySqlConn::column()
{
    return mysql_field_count(m_mysql); 
}

bool MySqlConn::next()
{
    if (nullptr != m_result)
    {
        m_row = mysql_fetch_row(m_result);
        if (nullptr != m_row)
        {
            return true;
        }
    }
    return false;
}

std::string MySqlConn::name(unsigned int index)
{
    if (index >= column())
    {
        return "";
    }

    MYSQL_FIELD *fields = mysql_fetch_fields(m_result);
    return fields[index].name; 
}

std::string MySqlConn::value(unsigned int index)
{
    if (index >= column() || index < 0)
    {
        return "";
    }

    char *row = m_row[index];
    unsigned long* len = mysql_fetch_lengths(m_result);
    return std::string(row, len[index]);

}

/*
std::string MySqlConn::value(unsigned int line, unsigned int column)
{
    if (line >= row()) || column >= column())
    {
        return "";
    }

    mysql_data_seek(m_result, line)

    unsigned long* len = mysql_fetch_lengths(m_result);
    m_row = mysql_fetch_row(m_result);
    return std::string(row[column], len[column]);
}
*/

bool MySqlConn::transcation()
{
    mysql_autocommit(m_mysql, false);
}

bool MySqlConn::commit()
{
    return mysql_commit(m_mysql);
}

bool MySqlConn::rollback()
{
    return mysql_rollback(m_mysql);
}

bool MySqlConn::setCharSet(const std::string& charset)
{
    int ret = mysql_set_character_set(m_mysql, charset.c_str());
    if (ret)
    {
        LOG_FMT_ERROR(g_sysLogger, "mysql set charset error, errorno: %d, errmsg: %s", errorno(), errmsg().c_str());
        return false;
    }
    return true;
}

void MySqlConn::freeResult()
{
    if (nullptr != m_result)
    {
        mysql_free_result(m_result);
        m_result = nullptr;
    }
}

unsigned int MySqlConn::errorno()
{
    return mysql_errno(m_mysql);
}

std::string MySqlConn::errmsg()
{
    return mysql_error(m_mysql);
}
} // namespace db 
